/*
 * CAN.c
 *
 * Created: 04.10.2012 11:35:04
 *  Author: bardbakk
 */ 
#include <avr/interrupt.h>

#include "definitions.h"
#include "MCP2515.h"
#include "CAN.h"
#include "USART.h"


void CAN_init()
{
	MCP2515_init();
	
	//Set loop-back mode
	//MCP2515_bit_modify(MCP_CANCTRL, MODE_MASK, MODE_LOOPBACK);
	//Set normal mode
	MCP2515_bit_modify(MCP_CANCTRL, 0b11100000, 0x00);
	
	
	
	//Receive all ids
	MCP2515_bit_modify(MCP_RXB0CTRL,0b01100000, 0xFF);
	
	//Enable external interrupt on falling edge: INT2
	BIT_SET(GICR, INT2);
	BIT_CLEAR(EMCUCR, ISC2);
	
	//Enable all receive interrupts
	MCP2515_bit_modify(MCP_CANINTE,0x3 ,MCP_RX_INT);
}

void CAN_message_send(CAN_message_t msg)
{
	int i;	
	//Set Standard ID high and low, respectively
	MCP2515_write(MCP_TXB0CTRL+1,(uint8_t)(msg.id>>3));
	MCP2515_write(MCP_TXB0CTRL+2,(uint8_t)(msg.id<<5));
		
	
	//Set message length (max 8 byte)
	MCP2515_write(MCP_TXB0CTRL+5, (0b00001111 & msg.length));
	
	//Set data registers
	for(i = 0; i < msg.length; i++)
	{
		MCP2515_write(MCP_TXB0CTRL+6+i,msg.data[i]);
	}
	MCP2515_request_to_send(0);
}

CAN_message_t*  CAN_message_receive()
{
	CAN_message_t* msg = malloc(sizeof(CAN_message_t));
	int i;
	//Read standard message ID, reads twice to fix bug	
	msg->id = (uint8_t)( MCP2515_read(MCP_RXB0SIDH) << 3);
	msg->id = (uint8_t)( MCP2515_read(MCP_RXB0SIDH) << 3);
	msg->id +=  (uint8_t)(MCP2515_read(MCP_RXB0SIDH+1) >> 5);
			
	//Read message length
	msg->length =(0b1111) & (MCP2515_read(MCP_RXB0SIDH+4));
			
	//Read message data
	for(i = 0; i<msg->length; i++)
	{
		msg->data[i] = MCP2515_read(MCP_RXB0SIDH+5+i); 
	}
	
	CAN_msg_rcvd = 0;
	MCP2515_bit_modify(MCP_CANINTF, 0x01,0x00);

	return msg;
}

ISR(INT2_vect)
{
	CAN_msg_rcvd = 1;
}